﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.LIB;
using YArchitech.Revit;

namespace YArchitech.Plumbing
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class LayPlumbingFixtures : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			FormBathroomLayout formBathroomLayout = new FormBathroomLayout(commandData.Application.ActiveUIDocument.Document);
			Transaction transaction = null;
			Transaction transaction2 = null;
			Transaction transaction3 = null;
			ElementId elementId = null;
			ListItemPlane listItemPlane = null;
			Document document = null;
			Result result;
			try
			{
				if (commandData == null)
				{
					throw new System.ArgumentNullException();
				}
				UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
				document = activeUIDocument.Document;
				Selection selection = activeUIDocument.Selection;
				if (!YJKRevitTools.ViewCheck(activeUIDocument, new List<ViewType>
				{
					(ViewType)1,
					(ViewType)2,
					(ViewType)4,
					(ViewType)3
				}))
				{
					result = Autodesk.Revit.UI.Result.Cancelled;
				}
				else
				{
					DialogResult dialogResult;
					for (;;)
					{
						dialogResult = formBathroomLayout.ShowDialog();
						if (dialogResult == DialogResult.Abort)
						{
							try
							{
								XYZ startPnt = activeUIDocument.Selection.PickPoint("请选择第一点...");
								XYZ endPnt = activeUIDocument.Selection.PickPoint("请选择第二点...");
								formBathroomLayout.SetAngelFromPoint(startPnt, endPnt);
								continue;
							}
							catch (Exception)
							{
								continue;
							}
							break;
						}
						break;
					}
					if (dialogResult != DialogResult.OK)
					{
						result = Autodesk.Revit.UI.Result.Succeeded;
					}
					else
					{
						HYEquipmentCommon hyequipmentCommon = new HYEquipmentCommon();
						ICollection<ElementId> allFamilyInstance = hyequipmentCommon.GetAllFamilyInstance(document, BuiltInCategory.OST_PlumbingFixtures);
						ICollection<Element> collectionId = null;
						ElementSet elementSet = null;
						listItemPlane = null;
						bool flag = false;
						bool flag2 = true;
						FamilySymbol fs = formBathroomLayout.fs;
						PlumbingFixturesParam plumbingFixturesPara = formBathroomLayout.plumbingFixturesPara;
						LayLineParameter lineParameter = formBathroomLayout.LineParameter;
						int layTerminalType = formBathroomLayout.layTerminalType;
						if (fs == null)
						{
							result = Autodesk.Revit.UI.Result.Cancelled;
						}
						else
						{
							if (fs != null)
							{
								ConnectHelper connectHelper = new ConnectHelper();
								if (listItemPlane != null)
								{
									if (4 == listItemPlane.PlaneType)
									{
										flag2 = true;
									}
									else
									{
										transaction2 = new Transaction(document, "创建平面");
										transaction2.Start();
										flag2 = false;
										if (2 == listItemPlane.PlaneType)
										{
											elementId = new ElementId(listItemPlane.PlaneId);
										}
										else
										{
											ReferencePlane referencePlane = document.Create.NewReferencePlane2(new XYZ(0.0, 0.0, listItemPlane.OffSet), new XYZ(0.0, 1.0, listItemPlane.OffSet), new XYZ(1.0, 0.0, listItemPlane.OffSet), document.ActiveView);
											if (referencePlane != null)
											{
												elementId = referencePlane.Id;
												if (this.CheckReferencePlaneName(document, listItemPlane.PlaneName))
												{
													string text = Guid.NewGuid().ToString();
													referencePlane.Name = text;
													listItemPlane.PlaneName = text;
												}
												else
												{
													referencePlane.Name = listItemPlane.PlaneName;
												}
												Parameter parameter = fs.GetParameter("装置类型");
												if (parameter != null && "地漏" == parameter.AsString())
												{
													referencePlane.Flip();
												}
											}
											document.Regenerate();
										}
										transaction2.Commit();
									}
								}
								if (layTerminalType == 0 && flag2)
								{
									flag = true;
									try
									{
										activeUIDocument.PromptForFamilyInstancePlacement(fs);
										goto IL_500;
									}
									catch (Exception)
									{
										goto IL_500;
									}
								}
								elementSet = new ElementSet();
								transaction3 = new Transaction(document, "卫浴装置布置");
								transaction3.Start();
								for (;;)
								{
									SubTransaction subTransaction = null;
									try
									{
										try
										{
											subTransaction = new SubTransaction(document);
											subTransaction.Start();
											if (!flag2 && layTerminalType == 0)
											{
												XYZ xyz = selection.PickPoint("选择一个点");
												elementSet = connectHelper.LayFamilyInstance(xyz, (document.GetElementById(elementId) as ReferencePlane).GetReference(), fs, document);
											}
											else if (layTerminalType == 1)
											{
												if (lineParameter != null)
												{
													ISelectionFilter selectionFilter = new DetailLineAndModelLineSelectionFilter();
													Reference reference = selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, selectionFilter, "请选择一条直线");
													Element element = document.GetElement(reference);
													XYZ globalPoint = reference.GlobalPoint;
													if (element.Location is LocationCurve)
													{
														Curve curve = (element.Location as LocationCurve).Curve;
														if (curve is Line)
														{
															YJKLine hyline = new YJKLine(curve as Line);
															List<XYZ> list = new List<XYZ>();
															if (lineParameter.LimitFlag == 1)
															{
																list = hyline.GetLayLineXYZList(globalPoint, lineParameter.Count, lineParameter.Ratio, UnitConvert.CovertToAPI(plumbingFixturesPara.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
															}
															else
															{
																list = hyline.GetLayLineXYZList(globalPoint, UnitConvert.LengthToStd(lineParameter.Distance / 1000.0), UnitConvert.LengthToStd(lineParameter.DistanceSide / 1000.0), UnitConvert.CovertToAPI(plumbingFixturesPara.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
															}
															if (list != null && list.Count > 0)
															{
																if (!flag2)
																{
																	elementSet = connectHelper.LayFamilyInstance(list, (document.GetElementById(elementId) as ReferencePlane).GetReference(), fs, document);
																}
																else
																{
																	elementSet = connectHelper.LayFamilyInstance(list, fs, document.ActiveView.GenLevel, 0, document);
																}
															}
															else
															{
																MessageBox.Show("布置失败", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
															}
														}
														else
														{
															MessageBox.Show("布置失败，请选择一条直线", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
														}
													}
												}
												else
												{
													MessageBox.Show("布置失败，沿线布置参数为空", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
												}
											}
											document.Regenerate();
											collectionId = hyequipmentCommon.GetAllTag(document, BuiltInCategory.OST_PlumbingFixtureTags);
											if (elementSet != null)
											{
												this.SettingParameter(document, elementSet, plumbingFixturesPara, collectionId, flag, flag2, listItemPlane);
											}
											subTransaction.Commit();
										}
										catch (Exception ex)
										{
											throw ex;
										}
										continue;
									}
									finally
									{
										if (subTransaction != null && (int)subTransaction.Commit() != 3)
										{
											subTransaction.RollBack();
										}
									}
									break;
								}
							}
							IL_500:
							if (flag)
							{
								transaction = new Transaction(document, "设置布置卫浴装置参数");
								transaction.Start();
								collectionId = hyequipmentCommon.GetAllTag(document, BuiltInCategory.OST_PlumbingFixtureTags);
								IEnumerable<ElementId> allFamilyInstance2 = hyequipmentCommon.GetAllFamilyInstance(document, BuiltInCategory.OST_PlumbingFixtures);
								elementSet = new ElementSet();
								foreach (ElementId elementId2 in allFamilyInstance2)
								{
									bool flag3 = false;
									foreach (ElementId elementId3 in allFamilyInstance)
									{
										if (elementId2 == elementId3)
										{
											flag3 = true;
											break;
										}
									}
									if (!flag3)
									{
										elementSet.Insert(document.GetElementById(elementId2));
									}
								}
								this.SettingParameter(document, elementSet, plumbingFixturesPara, collectionId, flag, flag2, listItemPlane);
								transaction.Commit();
							}
							result = Autodesk.Revit.UI.Result.Succeeded;
						}
					}
				}
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex2)
			{
				message = ex2.Message;
				result = Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				if (transaction3 != null && (int)transaction3.GetStatus() == 1)
				{
					transaction3.Commit();
				}
				if (transaction != null)
				{
					transaction.GetStatus();
				}
				if (transaction2 != null && (int)transaction2.GetStatus() != 3)
				{
					transaction2.RollBack();
				}
				if (null != elementId && listItemPlane != null && document != null && (1 == listItemPlane.PlaneType || listItemPlane.PlaneType == 0))
				{
					Transaction transaction4 = new Transaction(document, "删除临时平面");
					transaction4.Start();
					document.Delete(elementId);
					transaction4.Commit();
				}
			}
			return result;
		}

		private bool CheckReferencePlaneName(Autodesk.Revit.DB.Document doc, string name)
		{
			foreach (Element element in ((IEnumerable<Element>)YJKElementFilter.GetElementByCategory(doc, BuiltInCategory.OST_CLines)))
			{
				if (element is ReferencePlane && (element as ReferencePlane).Name == name)
				{
					return true;
				}
			}
			return false;
		}

		private void SettingParameter(Autodesk.Revit.DB.Document doc, ElementSet es, PlumbingFixturesParam plumbingFixturesPara, ICollection<Element> collectionId2, bool isLayPoint, bool isPlaneFlag, ListItemPlane planeParameter)
		{
			Element element = null;
			Element element2 = null;
			bool flag = true;
			foreach (object obj in es)
			{
				Element element3 = (Element)obj;
				if (element3 != null)
				{
					Location location = element3.Location;
					XYZ point = (element3.Location as LocationPoint).Point;
					element = element3;
					bool flag2 = false;
					foreach (Element element4 in collectionId2)
					{
						if (((IndependentTag)element4).TaggedLocalElementId.IntegerValue == element3.Id.IntegerValue)
						{
							flag2 = true;
							element2 = element4;
							collectionId2.Remove(element4);
							break;
						}
					}
					if (!flag2 && plumbingFixturesPara.Tag && flag)
					{
						try
						{
							RevitVersionFuncs.NewTag(doc, doc.ActiveView, new Reference(element), false, 0, 0, point);
							goto IL_100;
						}
						catch (Exception)
						{
							flag = false;
							MessageBox.Show("标注失败，可能原因是项目里没有标记族，请手动加载并配置", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
							goto IL_100;
						}
						goto IL_E7;
					}
					goto IL_E7;
					IL_100:
					if (isLayPoint && planeParameter == null && element.GetParameter(BuiltInParameter.FAMILY_LEVEL_PARAM) != null)
					{
						Parameter parameter = element.GetParameter(BuiltInParameter.FAMILY_LEVEL_PARAM);
						if (parameter.AsString() != null && "" != parameter.AsString())
						{
							parameter.Set(doc.ActiveView.GenLevel.Id);
						}
					}
					if (isPlaneFlag && planeParameter == null)
					{
						Parameter parameter2 = null;
						Parameter parameter3 = null;
						double num = 0.0;
						if (element.GetParameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM) != null)
						{
							parameter2 = element.GetParameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
						}
						if (parameter2 != null)
						{
							parameter2.Set(UnitConvert.CovertToAPI(plumbingFixturesPara.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
							num = parameter2.AsDouble();
						}
						if (num != UnitConvert.CovertToAPI(plumbingFixturesPara.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2))
						{
							if (element.GetParameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM) != null)
							{
								parameter3 = element.GetParameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM);
							}
							if (parameter3 != null)
							{
								parameter3.Set(UnitConvert.CovertToAPI(plumbingFixturesPara.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
							}
						}
					}
					if (Math.Abs(plumbingFixturesPara.Angle) > 0.0001)
					{
						Line line = Line.CreateBound(point, point + new XYZ(0.0, 0.0, 1.0));
						location.Rotate(line, plumbingFixturesPara.Angle / 180.0 * Math.PI);
					}
					doc.Regenerate();
					continue;
					IL_E7:
					if (flag2 && !plumbingFixturesPara.Tag)
					{
						doc.Delete(element2.Id);
						goto IL_100;
					}
					goto IL_100;
				}
			}
		}
	}
}
